<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">















 
 
 
 
 
 
 
  
  


<html>
  <head>
    <script type="text/javascript" language="JavaScript">
    ORIGINAL_PAGE_PATH = "/appengine/docs/python/datastore/entitiesandmodels.html";
    </script>
    
    
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Entities and Models - Google App Engine - Google Code</title>
<script type="text/javascript"><!--
(function(){function a(){this.t={};this.tick=function(c){this.t[c]=(new Date).getTime()};this.tick("start")}var b=new a;window.jstiming={Timer:a,load:b};if(window.external&&window.external.pageT)window.jstiming.pt=window.external.pageT;})();

var _tocPath_ = '/appengine/docs/_toc.ezt';
var codesite_token = null;
//--></script>
<link href="../../../../css/codesite.pack.04102009.css" type="text/css" rel="stylesheet"></link>
<script src="../../../../js/codesite_head.pack.04102009.js" type="text/javascript"></script>
<script type="text/javascript">CODESITE_CSITimer['load'].tick('bhs');</script>
<link rel="search" type="application/opensearchdescription+xml" title="Google Code" href="http://code.google.com/osd.xml" />

<!--[if IE]><link rel="stylesheet" type="text/css" href="../../../../css/iehacks.css" /><![endif]-->

    <link href="../../../../css/semantic_headers.css" rel="stylesheet" type="text/css" />
    <link href="../../../css/local_extensions.css" rel="stylesheet" type="text/css" />
  </head>

  <body class="gc-documentation">

    
    
    
</a>

<div id="gb">
 <span>
  
    <a id="lang-dropdown" class="dropdown" href="http://code.google.com" onclick="return false;"><img class="globeicon" src="../../../../images/globe2_small.png"/><span>English</span></a>
  
 </span>
</div>

<div class="gbh" style="left: 0pt;"></div>
<div class="gbh" style="right: 0pt;"></div>


<style type="text/css">
  #gc-topnav h1 {
    padding: 0 0 0 6px;
  }
</style>


<div id="gc-container">
<a name="top"></a>
<div id="skipto">
  <a href="#gc-pagecontent">Skip to page content</a>
  <a href="#gc-toc">Skip to main navigation</a>
</div>

<div id="gc-header">
  <div id="logo"><a href="http://code.google.com">
  
  
     <img src="../../../../images/cleardot.gif" height="1px" width="1px" alt="Google Code Home Page" id="gc-logo-img"/>
  
  
  </a></div>
  <div id="search">
    <div id="searchForm" class="searchForm">
      <form id="cse" action="http://www.google.com/cse" accept-charset="utf-8" class="gsc-search-box" onsubmit="executeGSearch(document.getElementById('gsearchInput').value); return false;">
      <noscript>
      <input type="hidden" name="cref" value="http://code.google.com/cse/googlecode-context.xml"/>
      </noscript>
        <table class="gsc-search-box" cellpadding="0" cellspacing="0">
          <tbody>
            <tr>
              <td class="gsc-input">
                <input id="gsearchInput" type="text" name="q" maxlength="2048" class="gsc-input" autocomplete="off" title="Google Code Search" style="width:345px"/>
              </td>
              <td class="gsc-search-button">
                <div id="cs-searchresults" onclick="event.cancelBubble = true;"></div>
                <input title="Search" id="gsearchButton" class="gsc-search-button" name="sa" value="Search" type="submit"/>
              </td>
            </tr>
            <tr>
              <td colspan="2" class="greytext">e.g. "templates" or "datastore"</td>
            </tr>
          </tbody>
        </table>
      </form>
    </div> <!-- end searchForm -->
  </div> <!-- end search -->
</div> <!-- end gc-header -->


<div id="codesiteContent">

<a name="gc-topnav-anchor"></a>
<div id="gc-topnav">
  <h1>Google App Engine</h1>
  <ul id="docs" class="gc-topnav-tabs">

    <li id="home_link">
      <a href="../../../index.html" title="Google App Engine home page">Home</a>
    </li>
  
    <li id="docs_link">
      <a href="../../index.html" class="selected" title="Official Google App Engine documentation">Docs</a>
    </li>
  
    <li id="faq_link">
      <a href="../../../kb/index.html" title="Answers to frequently asked questions about Google App Engine">FAQ</a>
    </li>
  
    <li id="articles_link">
      <a href="../../../articles/index.html" title="Focused articles and tutorials for Google App Engine developers">Articles</a>
    </li>
  
    <li>
      <a href="http://googleappengine.blogspot.com/" title="Official Google App Engine blog">Blog</a>
    </li>
  
    <li>
      <a href="../../../community.html" title="Community home for Google App Engine">Community</a>
    </li>
  
    <li>
      <a href="../../../terms.html" title="Google App Engine terms of service">Terms</a>
    </li>
  
    <li>
      <a href="../../../downloads.html" title="Download Google App Engine">Download</a>
    </li>
  

  </ul>
</div> <!-- end gc-topnav -->

    <div class="g-section g-tpl-170">

      <div class="g-unit g-first" id="gc-toc">
        <ul>
  <li><a href="../../../downloads.html">Downloads</a></li>
  <li><a href="http://code.google.com/status/appengine">System Status</a></li>
  <li><a href="http://code.google.com/p/googleappengine/issues/list">Issue Tracker</a></li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Getting Started</h2>
    <ul>
      <li><a href="../../whatisgoogleappengine.html">What Is Google App Engine?</a></li>
      <li><a href="../../java/gettingstarted/index.html">Java</a>
        <ul>
              <li><a href="../../java/gettingstarted/introduction.html">Introduction</a></li>
    <li><a href="../../java/gettingstarted/installing.html">Installing the Java SDK</a></li>
    <li><a href="../../java/gettingstarted/creating.html">Creating a Project</a></li>
    <li><a href="../../java/gettingstarted/usingusers.html">Using the Users Service</a></li>
    <li><a href="../../java/gettingstarted/usingjsps.html">Using JSPs</a></li>
    <li><a href="../../java/gettingstarted/usingdatastore.html">Using the Datastore with JDO</a></li>
    <li><a href="../../java/gettingstarted/staticfiles.html">Using Static Files</a></li>
    <li><a href="../../java/gettingstarted/uploading.html">Uploading Your Application</a></li>

        </ul>
      </li>
      <li><a href="../gettingstarted/index.html">Python</a>
        <ul>
            <li><a href="../gettingstarted/introduction.html">Introduction</a></li>
  <li><a href="../gettingstarted/devenvironment.html">The Development Environment</a></li>
  <li><a href="../gettingstarted/helloworld.html">Hello, World!</a></li>
  <li><a href="../gettingstarted/usingwebapp.html">Using the webapp Framework</a></li>
  <li><a href="../gettingstarted/usingusers.html">Using the Users Service</a></li>
  <li><a href="../gettingstarted/handlingforms.html">Handling Forms With webapp</a></li>
  <li><a href="../gettingstarted/usingdatastore.html">Using the Datastore</a></li>
  <li><a href="../gettingstarted/templates.html">Using Templates</a></li>
  <li><a href="../gettingstarted/staticfiles.html">Using Static Files</a></li>
  <li><a href="../gettingstarted/uploading.html">Uploading Your Application</a></li>

        </ul>
      </li>
    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Java <sup class="new">Early Look</sup></h2>
    <ul>
          <li><a href="../../java/overview.html">Overview</a></li>
    <li><a href="../../java/runtime.html">Servlet Environment</a></li>
    <li><a href="../../java/datastore/index.html">Storing Data</a>
      <ul>
            <li><a href="../../java/datastore/overview.html">Overview</a></li>
    <li><a href="../../java/datastore/usingjdo.html">Using JDO</a></li>
    <li><a href="../../java/datastore/dataclasses.html">Defining Data Classes</a></li>
    <li><a href="../../java/datastore/creatinggettinganddeletingdata.html">Creating, Getting and Deleting Data</a></li>
    <li><a href="../../java/datastore/queriesandindexes.html">Queries and Indexes</a></li>
    <li><a href="../../java/datastore/transactions.html">Transactions</a></li>
    <li><a href="../../java/datastore/relationships.html">Relationships</a></li>
    <li><a href="../../java/datastore/usingjpa.html">Using JPA</a></li>
    <li><a href="../../java/javadoc/com/google/appengine/api/datastore/package-summary.html">Low-level API</a></li>

      </ul>
    </li>
    <li><a href="../../java/apis.html">Services</a>
      <ul>
        <li><a href="../../java/memcache/index.html">Memcache</a>
          <ul>
                <li><a href="../../java/memcache/overview.html">Overview</a></li>
    <li><a href="../../java/memcache/usingjcache.html">Using JCache</a></li>
    <li><a href="../../java/javadoc/com/google/appengine/api/memcache/package-summary.html">Low-level API</a></li>

          </ul>
        </li>
        <li><a href="../../java/urlfetch/index.html">URL Fetch</a>
          <ul>
                <li><a href="../../java/urlfetch/overview.html">Overview</a></li>
    <li><a href="../../java/urlfetch/usingjavanet.html">Using java.net</a></li>
    <li><a href="../../java/javadoc/com/google/appengine/api/urlfetch/package-summary.html">Low-level API</a></li>

          </ul>
        </li>
        <li><a href="../../java/mail/index.html">Mail</a>
          <ul>
                <li><a href="../../java/mail/overview.html">Overview</a></li>
    <li><a href="../../java/mail/usingjavamail.html">Using JavaMail</a></li>
    <li><a href="../../java/javadoc/com/google/appengine/api/mail/package-summary.html">Low-level API</a></li>

          </ul>
        </li>
        <li><a href="../../java/images/index.html">Images</a>
          <ul>
                <li><a href="../../java/images/overview.html">Overview</a></li>
    <li><a href="../../java/javadoc/com/google/appengine/api/images/package-summary.html">API Reference</a></li>

          </ul>
        </li>
        <li><a href="../../java/users/index.html">Google Accounts</a>
          <ul>
                <li><a href="../../java/users/overview.html">Overview</a></li>
    <li><a href="../../java/javadoc/com/google/appengine/api/users/package-summary.html">API Reference</a></li>

          </ul>
        </li>
      </ul>
    </li>
    <li><a href="../../java/javadoc/index.html">Javadoc Reference</a></li>
    <li><a href="../../java/jrewhitelist.html">JRE Class White List</a></li>
    <li><a href="../../java/config/index.html">Configuration</a>
      <ul>
            <li><a href="../../java/config/webxml.html">Deployment Descriptor</a></li>
    <li><a href="../../java/config/appconfig.html">App Config</a></li>
    <li><a href="../../java/config/indexconfig.html">Index Config</a></li>
    <li><a href="../../java/config/cron.html">Scheduled Tasks</a></li>

      </ul>
    </li>
    <li><a href="../../java/tools/index.html">Tools</a>
      <ul>
            <li><a href="../../java/tools/devserver.html">Development Server</a></li>
    <li><a href="../../java/tools/uploadinganapp.html">Uploading and Managing</a></li>
    <li><a href="../../java/tools/eclipse.html">Google Plugin for Eclipse</a></li>
    <li><a href="../../java/tools/ant.html">Using Apache Ant</a></li>

      </ul>
    </li>
    <li><a href="../../java/howto/index.html">How-To</a>
      <ul>
              <li><a href="../../java/howto/unittesting.html">Unit Testing</a></li>

      </ul>
    </li>

    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Python</h2>
    <ul>
          <li><a href="../overview.html">Overview</a></li>
    <li><a href="../runtime.html">CGI Environment</a></li>
    <li><a href="index.html">Storing Data</a>
      <ul>
             <li><a href="overview.html">Overview</a></li>
     <li><a href="entitiesandmodels.html">Entities and Models</a></li>
     <li><a href="creatinggettinganddeletingdata.html">Creating, Getting and Deleting Data</a></li>
     <li><a href="keysandentitygroups.html">Keys and Entity Groups</a></li>
     <li><a href="queriesandindexes.html">Queries and Indexes</a></li>
     <li><a href="transactions.html">Transactions</a></li>
     <li><a href="typesandpropertyclasses.html">Types and Property Classes</a></li>
     <li><a href="gqlreference.html">GQL Reference</a></li>

     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="modelclass.html">Model</a></li>
         <li><a href="expandoclass.html">Expando</a></li>
         <li><a href="polymodelclass.html">PolyModel</a></li>
         <li><a href="propertyclass.html">Property</a></li>
         <li><a href="queryclass.html">Query</a></li>
         <li><a href="gqlqueryclass.html">GqlQuery</a></li>
         <li><a href="keyclass.html">Key</a></li>
         <li><a href="functions.html">Functions</a></li>
         <li><a href="exceptions.html">Exceptions</a></li>
       </ul>
     </li>

      </ul>
    </li>
    <li><a href="../apis.html">Services</a>
      <ul>
        <li><a href="../memcache/index.html">Memcache</a>
          <ul>
                 <li><a href="../memcache/overview.html">Overview</a></li>
      <li><a href="../memcache/usingmemcache.html">Using Memcache</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../memcache/clientclass.html">Client</a></li>
         <li><a href="../memcache/functions.html">Functions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../urlfetch/index.html">URL Fetch</a>
          <ul>
                 <li><a href="../urlfetch/overview.html">Overview</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../urlfetch/fetchfunction.html">The fetch Function</a></li>
         <li><a href="../urlfetch/responseobjects.html">Response Objects</a></li>
         <li><a href="../urlfetch/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../mail/index.html">Mail</a>
          <ul>
                 <li><a href="../mail/overview.html">Overview</a></li>
     <li><a href="../mail/sendingmail.html">Sending Mail</a></li>
     <li><a href="../mail/attachments.html">Attachments</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../mail/emailmessageclass.html">EmailMessage</a></li>
         <li><a href="../mail/emailmessagefields.html">Message Fields</a></li>
         <li><a href="../mail/functions.html">Functions</a></li>
         <li><a href="../mail/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../images/index.html">Images</a>
          <ul>
                 <li><a href="../images/overview.html">Overview</a></li>
     <li><a href="../images/installingPIL.html">Installing PIL</a></li>
     <li><a href="../images/usingimages.html">Using the Images API</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../images/imageclass.html">Image</a></li>
         <li><a href="../images/functions.html">Functions</a></li>
         <li><a href="../images/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../users/index.html">Google Accounts</a>
          <ul>
                 <li><a href="../users/overview.html">Overview</a></li>
     <li><a href="../users/userobjects.html">User Objects</a></li>
     <li><a href="../users/loginurls.html">Login URLs</a></li>
     <li><a href="../users/adminusers.html">Admin Users</a></li>

     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../users/userclass.html">User</a></li>
         <li><a href="../users/functions.html">Functions</a></li>
         <li><a href="../users/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
      </ul>
    </li>
    <li><a href="../config/index.html">Configuration</a>
      <ul>
            <li><a href="../config/appconfig.html">App Config</a></li>
    <li><a href="../config/indexconfig.html">Index Config</a></li>
    <li><a href="../config/cron.html">Scheduled Tasks</a></li>

      </ul>
    </li>
    <li><a href="../tools/index.html">Tools</a>
      <ul>
            <li><a href="../tools/devserver.html">Development Server</a></li>
    <li><a href="../tools/uploadinganapp.html">Uploading and Managing</a></li>
    <li><a href="../tools/uploadingdata.html">Uploading Data</a></li>
    <li><a href="../tools/webapp/index.html">webapp Framework</a>
      <ul>
             <li><a href="../tools/webapp/overview.html">Overview</a></li>
     <li><a href="../tools/webapp/running.html">Running the Application</a></li>
     <li><a href="../tools/webapp/requesthandlers.html">Request Handlers</a></li>
     <li><a href="../tools/webapp/requestdata.html">Request Data</a></li>
     <li><a href="../tools/webapp/buildingtheresponse.html">Building the Response</a></li>
     <li><a href="../tools/webapp/redirects.html">Redirects, Headers and Status Codes</a></li>
     

     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../tools/webapp/requestclass.html">Request</a></li>
         <li><a href="../tools/webapp/responseclass.html">Response</a></li>
         <li><a href="../tools/webapp/requesthandlerclass.html">RequestHandler</a></li>
         <li><a href="../tools/webapp/wsgiapplicationclass.html">WSGIApplication</a></li>
         <li><a href="../tools/webapp/utilmodule.html">Utility Functions</a></li>
         
       </ul>
     </li>

      </ul>
    </li>
    <li><a href="../tools/libraries.html">Third-party Libraries</a></li>

      </ul>
    </li>
    <li><a href="../howto/index.html">How-To</a>
      <ul>
              <li><a href="../howto/usinggdataservices.html">Google Data Services</a></li>

      </ul>
    </li>

    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Managing Your App</h2>
    <ul>
      <li><a href="../../theadminconsole.html">The Admin Console</a></li>
      <li><a href="../../quotas.html">Quotas</a></li>
      <li><a href="../../billing.html">Billing</a></li>
    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Resources</h2>
    <ul>
      <li><a href="../../../kb/index.html">FAQ</a></li>
      <li><a href="../../../articles/index.html">Articles</a></li>
      <li><a href="http://appengine-cookbook.appspot.com/">Cookbook</a></li>
      <li><a href="http://appgallery.appspot.com/">App Gallery</a></li>
      <li><a href="http://code.google.com/p/googleappengine/">SDK Code</a></li>
      <li><a href="http://code.google.com/p/google-app-engine-samples/">Sample Apps Code</a></li>
      <li><a href="../../../community.html">Discussion Groups</a></li>
    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><a href="../../roadmap.html">Product Roadmap</a></li>
  <li><a href="http://code.google.com/p/googleappengine/wiki/SdkReleaseNotes">Release Notes</a></li>
  <li><a href="../../revision_history.html">Revision History</a></li>
</ul>

        <a class="hidden" href="#gc-topnav-anchor">More Google App Engine resource links</a>
      </div>

      <div class="g-unit" id="gc-pagecontent">
        <h1 class="page_title">Entities and Models</h1>



<p>A datastore entity has a key and a set of properties.  An application uses the datastore API to define data models, and create instances of those models to be stored as entities.  Models provide a common structure to the entities created by the API, and can define rules for validating property values.</p>

<ul>
  <li><a href="#The_Model_Interface">The Model Interface</a></li>
  <li><a href="#Expando_Models">Expando Models</a></li>
  <li><a href="#Polymorphic_Models">Polymorphic Models</a></li>
  <li><a href="#Properties_and_Types">Properties and Types</a>
    <ul>
      <li><a href="#Strings_Long_Strings_and_Blobs">Strings and Blobs</a></li>
      <li><a href="#Lists">Lists</a></li>
      <li><a href="#References">References</a></li>
    </ul>
  </li>
  <li><a href="#Property_Names">Property_Names</a></li>
</ul>


<h2 id="The_Model_Interface">The Model Interface</h2>

<p>An application describes the kinds of data it uses with <i>models</i>.  A model is a Python class that inherits from the <a href="modelclass.html">Model</a> class.  The model class defines a new kind of datastore entity and the properties the kind is expected to take.</p>

<p>Model properties are defined using class attributes on the model class.  Each class attribute is an instance of a subclass of the <a href="propertyclass.html">Property</a> class, usually one of <a href="typesandpropertyclasses.html">the provided property classes</a>.  A property instance holds configuration for the property, such as whether or not the property is required for the instance to be valid, or a default value to use for the instance if none is provided.</p>

<pre class="prettyprint">
from google.appengine.ext import db

class Pet(db.Model):
  name = db.StringProperty(required=True)
  type = db.StringProperty(required=True, choices=set(["cat", "dog", "bird"]))
  birthdate = db.DateProperty()
  weight_in_pounds = db.IntegerProperty()
  spayed_or_neutered = db.BooleanProperty()
  owner = db.UserProperty(required=True)
</pre>

<p>An entity of one of the defined entity kinds is represented in the API by an instance of the corresponding model class.  The application can create a new entity by calling the constructor of the class.  The application accesses and manipulates properties of the entity using attributes of the instance.  The model instance constructor accepts initial values for properties as keyword arguments.</p>

<pre class="prettyprint">
from google.appengine.api import users

pet = Pet(name="Fluffy",
          type="cat",
          owner=users.get_current_user())
pet.weight_in_pounds = 24
</pre>

<p class="note"><b>Note:</b> The attributes of the model <i>class</i> are configuration for the model properties, whose values are <a href="propertyclass.html">Property</a> instances.  The attributes of the model <i>instance</i> are the actual property values, whose values are of the type accepted by the Property class.</p>

<p>The Model class uses the Property instances to validate values assigned to the model instance attributes.  Property value validation occurs when a model instance is first constructed, and when an instance attribute is assigned a new value.  This ensures that a property can never have an invalid value.</p>

<p>Because validation occurs when the instance is constructed, any property that is configured to be required must be initialized in the constructor.  In this example, <code>name</code>, <code>type</code> and <code>owner</code> are all required values, so their initial values are specified in the constructor.  <code>weight_in_pounds</code> is not required by the model, so it starts out unassigned, then is assigned a value later.</p>

<p>An instance of a model created using the constructor does not exist in the datastore until it is "put" for the first time.  See <a href="creatinggettinganddeletingdata.html">Creating, Getting and Deleting Data</a>.</p>

<p class="note"><b>Note:</b> As with all Python class attributes, model property configuration is initialized when the script or module is first imported.  Because App Engine caches imported modules between requests, module configuration may be initialized during a request for one user, and re-used during a request for another.  Do not initialize model property configuration, such as default values, with data specific to the request or the current user.  See <a href="../runtime.html#App_Caching">App Caching</a> for more information.</p>


<h2 id="Expando_Models">Expando Models</h2>

<p>A model defined using the Model class establishes a fixed set of properties that every instance of the class must have (perhaps with default values).  This is a useful way to model data objects, but the datastore does not require that every entity of a given kind have the same set of properties.</p>

<p>Sometimes it is useful for an entity to have properties that aren't necessarily like the properties of other entities of the same kind.  Such an entity is represented in the datastore API by an "expando" model.  An expando model class subclasses the <a href="expandoclass.html">Expando</a> superclass.  Any value assigned to an attribute of an instance of an expando model becomes a property of the datastore entity, using the name of the attribute.  These properties are known as <i>dynamic properties</i>.  Properties defined using Property class instances in class attributes are <i>fixed properties</i>.</p>

<p>An expando model can have both fixed and dynamic properties.  The model class simply sets class attributes with Property configuration objects for the fixed properties.  The application creates dynamic properties when it assigns them values.</p>

<pre class="prettyprint">
class Person(db.Expando):
  first_name = db.StringProperty()
  last_name = db.StringProperty()
  hobbies = db.StringListProperty()

p = Person(first_name="Albert", last_name="Johnson")
p.hobbies = ["chess", "travel"]

p.chess_elo_rating = 1350

p.travel_countries_visited = ["Spain", "Italy", "USA", "Brazil"]
p.travel_trip_count = 13
</pre>

<p>Because dynamic properties do not have model property definitions, dynamic properties are not validated.  Any dynamic property can have a value of any of <a href="typesandpropertyclasses.html">the datastore base types</a>, including <code>None</code>.  Two entities of the same kind can have different types of values for the same dynamic property, and one can leave a property unset that the other sets.</p>

<p>Unlike fixed properties, dynamic properties need not exist.  A dynamic property with a value of <code>None</code> is different from a non-existent dynamic property.  If an expando model instance does not have an attribute for a property, the corresponding data entity does not have that property.  You can delete a dynamic property by deleting the attribute.</p>

<pre class="prettyprint">
del p.chess_elo_rating
</pre>

<p>A query that uses a dynamic property in a filter will only return entities whose value for the property is of the same type as the value used in the query.  Similarly, the query will only return entities with that property set.</p>

<pre class="prettyprint">
p1 = Person()
p1.favorite = 42
p1.put()

p2 = Person()
p2.favorite = "blue"
p2.put()

p3 = Person()
p3.put()

people = db.GqlQuery("SELECT * FROM Person WHERE favorite < :1", 50)
# people has p1, but not p2 or p3

people = db.GqlQuery("SELECT * FROM Person WHERE favorite > :1", 50)
# people has no results
</pre>

<p>The <a href="expandoclass.html">Expando</a> class is a subclass of the <a href="modelclass.html">Model</a> class, and inherits all of its methods.</p>


<h2 id="Polymorphic_Models">Polymorphic Models</h2>

<p>The Python API includes a another class for data modeling that allows you to define hierarchies of classes, and perform queries that can return entities of a given class or any of its subclasses.  Such models and queries are called "polymorphic," because they allow instances of one class to be results for a query of a parent class.</p>

<p>The following example defines an <code>Contact</code> class, and <code>Person</code> and <code>Company</code> classes that are subclasses of <code>Contact</code>:</p>

<pre class="prettyprint">
from google.appengine.ext import db
from google.appengine.ext.db import polymodel

class Contact(polymodel.PolyModel):
  phone_number = db.PhoneNumberProperty()
  address = db.PostalAddressProperty()

class Person(Contact):
  first_name = db.StringProperty()
  last_name = db.StringProperty()
  mobile_number = db.PhoneNumberProperty()

class Company(Contact):
  name = db.StringProperty()
  fax_number = db.PhoneNumberProperty()
</pre>

<p>This model ensures that all <code>Person</code> entities and all <code>Company</code> entities have <code>phone_number</code> and <code>address</code> properties, and queries for <code>Contact</code> entities can return either <code>Person</code> or <code>Company</code> entities.  Only <code>Person</code> entities have <code>mobile_number</code> properties.</p>

<p>The subclasses can be instantiated just like any other model class:</p>

<pre class="prettyprint">
p = Person(phone_number='1-206-555-9234',
           address='123 First Ave., Seattle, WA, 98101',
           first_name='Alfred',
           last_name='Smith',
           mobile_number='1-206-555-0117')
p.put()

c = Company(phone_number='1-503-555-9123',
            address='P.O. Box 98765, Salem, OR, 97301',
            name='Data Solutions, LLC',
            fax_number='1-503-555-6622')
c.put()
</pre>

<p>A query for <code>Contact</code> entities can return instances of either <code>Contact</code>, <code>Person</code> or <code>Company</code>.  The following code prints information for both entities created above:</p>

<pre class="prettyprint">
for contact in Contact.all():
  print 'Phone: %s\nAddress: %s\n\n'
        % (contact.phone,
           contact.address))
</pre>

<p>A query for <code>Company</code> entities returns only instances of <code>Company</code>:</p>

<pre class="prettyprint">
for company in Company.all()
  # ...
</pre>

<p>For more information on how to use polymorphic models, and how they are implemented, see <a href="polymodelclass.html">The PolyModel Class</a>.</p>


<h2 id="Properties_and_Types">Properties and Types</h2>

<p>The datastore supports a fixed set of value types for entity properties, including Unicode strings, integers, floating point numbers, dates, entity keys, byte strings (blobs), and various GData types.  Each of the datastore value types has a corresponding Property class provided by the <code>google.appengine.ext.db</code> module.</p>

<p><a href="typesandpropertyclasses.html">Types and Property Classes</a> describes all of the supported value types and their corresponding Property classes.  Several special value types are described below.</p>

<h3 id="Strings_Long_Strings_and_Blobs">Strings and Blobs</h3>

<p>The datastore supports two value types for storing text: short text strings up to 500 bytes in length, and long text strings up to 1 megabyte in length.  Short strings are indexed and can be used in query filter conditions and sort orders.  Long strings are not indexed and cannot be used in filter conditions or sort orders.</p>

<p>A short string value can be either a <code>unicode</code> value or a <code>str</code> value.  If the value is a <code>str</code>, an encoding of <code>'ascii'</code> is assumed.  To specify a different encoding for a <code>str</code> value, you can convert it to a <code>unicode</code> value with the <code>unicode()</code> type constructor, which takes the <code>str</code> and the name of the encoding as arguments.  Short strings can be modeled using the <a href="typesandpropertyclasses.html#StringProperty">StringProperty</a> class.</p>

<pre class="prettyprint">
class MyModel(db.Model):
  string = db.StringProperty()

obj = MyModel()

# Python Unicode literal syntax fully describes characters in a text string.
obj.string = u"kittens"

# unicode() converts a byte string to a Unicode value using the named codec.
obj.string = unicode("kittens", "latin-1")

# A byte string is assumed to be text encoded as ASCII (the 'ascii' codec).
obj.string = "kittens"

# Short string properties can be used in query filters.
results = db.GqlQuery("SELECT * FROM MyModel WHERE string = :1", u"kittens")
</pre>

<p>A long string value is represented by a <a href="typesandpropertyclasses.html#Text">db.Text</a> instance.  Its constructor takes either a <code>unicode</code> value, or a <code>str</code> value and optionally the name of the encoding used in the <code>str</code>.  Long strings can be modeled using the <a href="typesandpropertyclasses.html#TextProperty">TextProperty</a> class.</p>

<pre class="prettyprint">
class MyModel(db.Model):
  text = db.TextProperty()

obj = MyModel()

# Text() can take a Unicode value.
obj.text = db.Text(u"lots of kittens")

# Text() can take a byte string and the name of an encoding.
obj.text = db.Text("lots of kittens", "latin-1")

# If no encoding is specified, a byte string is assumed to be ASCII text.
obj.text = db.Text("lots of kittens")

# Text properties can store large values.
obj.text = db.Text(open("a_tale_of_two_cities.txt").read(), "utf-8")
</pre>

<p>The datastore also supports two similar types for non-text byte strings: <a href="typesandpropertyclasses.html#ByteString">db.ByteString</a> and <a href="typesandpropertyclasses.html#Blob">db.Blob</a>.  These values are strings of raw bytes, and are not treated as encoded text (such as UTF-8).</p>

<p>Like <code>str</code> or <code>unicode</code> values, <code>db.ByteString</code> values are indexed, and limited to 500 characters.  A <code>ByteString</code> instance represents a short string of bytes, and takes a <code>str</code> value as an argument to its constructor.  Byte strings are modeled using the <a href="typesandpropertyclasses.html#ByteStringProperty">ByteStringProperty</a> class.</p>

<p>Like <code>db.Text</code>, a <code>db.Blob</code> value can be as large as 1 megabyte, but is not indexed, and cannot be used in query filters or sort orders.  The <code>db.Blob</code> class takes a <code>str</code> value as an argument to its constructor.  Blobs are modeled using the <a href="typesandpropertyclasses.html#BlobProperty">BlobProperty</a> class.</p>

<pre class="prettyprint">
class MyModel(db.Model):
  blob = db.BlobProperty()

obj = MyModel()

obj.blob = db.Blob(open("image.png").read())
</pre>


<h3 id="Lists">Lists</h3>

<p>A property can have multiple values, represented in the datastore API as a Python <code>list</code>.  The list can contain values of any of the value types supported by the datastore. A single list property may even have values of different types. Order is preserved, so when entities are returned by queries and <a href="functions.html#get">get()</a>, list properties will have values in the same order as when they were stored.</p>

<p>The <a href="typesandpropertyclasses.html#ListProperty">ListProperty</a> class models a list, and enforces that all values in the list are of a given type.  For convenience, the library also provides <a href="typesandpropertyclasses.html#StringListProperty">StringListProperty</a>, similar to <code>ListProperty(basestring)</code>.</p>

<pre class="prettyprint">
class MyModel(db.Model):
  numbers = db.ListProperty(long)

obj = MyModel()
obj.numbers = [2, 4, 6, 8, 10]

obj.numbers = ["hello"]  # ERROR: MyModel.numbers must be a list of longs.
</pre>

<p>A query filter on a list property tests the given value against members of the list.  The condition is true if at least one member of the list meets the condition.</p>

<pre class="prettyprint">
# Get all entities where numbers contains a 6.
results = db.GqlQuery("SELECT * FROM MyModel WHERE numbers = 6")

# Get all entities where numbers contains at least one element less than 10.
results = db.GqlQuery("SELECT * FROM MyModel WHERE numbers &lt; 10")
</pre>

<p>Query filters only operate on the list members.  There is no way to test two lists for similarity in a query filter.</p>

<p>Internally, the datastore represents a list property value as multiple values for the property.  If a list property value is the empty list, then the property has no representation in the datastore.  The datastore API treats this situation differently for static properties (with ListProperty) and dynamic properties:</p>
<ul class="doublespace">
  <li>A static ListProperty can be assigned the empty list as a value.  The property does not exist in the datastore, but the model instance behaves as if the value is the empty list.  A static ListProperty <i>cannot</i> have a value of <code>None</code>.</li>
  <li>A dynamic property with a <code>list</code> value <i>cannot</i> be assigned an empty list value.  However, it can have a value of <code>None</code>, and can be deleted (using <code>del</code>).</li>
</ul>

<p>The ListProperty model tests that a value added to the list is of the correct type, and throws a BadValueError if it isn't.  This test occurs (and potentially fails) even when a previously stored entity is retrieved and loaded into the model.  Because <code>str</code> values are converted to <code>unicode</code> values (as ASCII text) prior to storage, <code>ListProperty(str)</code> is treated as <code>ListProperty(basestring)</code>, the Python data type which accepts both <code>str</code> and <code>unicode</code> values.  You can also use <code>StringListProperty()</code> for this purpose.</p>

<p>For storing non-text byte strings, use <a href="typesandpropertyclasses.html#Blob">db.Blob</a> values.  The bytes of a blob string are preserved when they are stored and retrieved.  You can declare a property that is a list of blobs as <code>ListProperty(db.Blob)</code>.</p>

<p>List properties interact in unusual ways with sort orders. See <a href="queriesandindexes.html">Queries and Indexes: Sort Orders and Properties With Multiple Values</a> for details.


<h3 id="References">References</h3>

<p>A property value can contain the key of another entity.  The value is a <a href="keyclass.html">Key</a> instance.</p>

<p>The <a href="typesandpropertyclasses.html#ReferenceProperty">ReferenceProperty</a> class models a key value, and enforces that all values refer to entities of a given kind.  For convenience, the library also provides <a href="typesandpropertyclasses.html#SelfReferenceProperty">SelfReferenceProperty</a>, equivalent to a ReferenceProperty that refers to the same kind as the entity with the property.</p>

<p>Assigning a model instance to a ReferenceProperty property automatically uses its key as the value.</p>

<pre class="prettyprint">
class FirstModel(db.Model):
  prop = db.IntegerProperty()

class SecondModel(db.Model):
  reference = db.ReferenceProperty(FirstModel)

obj1 = FirstModel()
obj1.prop = 42
obj1.put()

obj2 = SecondModel()

# A reference value is the key of another entity.
obj2.reference = obj1.key()

# Assigning a model instance to a property uses the entity's key as the value.
obj2.reference = obj1
obj2.put()
</pre>

<p>A ReferenceProperty property value can be used as if it were the model instance of the referenced entity.  If the referenced entity is not in memory, using the property as an instance automatically fetches the entity from the datastore.</p>

<pre class="prettyprint">
obj2.reference.prop = 999
obj2.reference.put()

results = db.GqlQuery("SELECT * FROM SecondModel")
another_obj = results.fetch(1)[0]
v = another_obj.reference.prop
</pre>

<p>When an entity whose key is the value of a reference property is deleted, the reference property does not change.  A reference property value can be a key that is no longer valid.  If an application expects that a reference could be invalid, it can test for the existence of the object using an <code>if</code> statement:</p>

<pre class="prettyprint">
obj1 = obj2.reference

if not obj1:
  # Referenced entity was deleted.
</pre>

<p>ReferenceProperty has another handy feature: back-references.  When a model has a ReferenceProperty to another model, each referenced entity gets a property whose value is a <a href="queryclass.html">Query</a> that returns all of the entities of the first model that refer to it.</p>

<pre class="prettyprint">
# To fetch and iterate over every SecondModel entity that refers to the
# FirstModel instance obj1:
for obj in obj1.secondmodel_set:
  # ...
</pre>

<p>The name of the back-reference property defaults to <code>modelname_set</code> (with the name of the model class in lowercase letters, and "_set" added to the end), and can be adjusted using the <code>collection_name</code> argument to the ReferenceProperty constructor.</p>

<p>If you have multiple ReferenceProperty values that refer to the same model class, the default construction of the back-reference property will raise an error:

<pre class="prettyprint">
class FirstModel(db.Model):
  prop = db.IntegerProperty()

# This class raises a DuplicatePropertyError with the message
# "Class Firstmodel already has property secondmodel_set"
class SecondModel(db.Model):
  reference_one = db.ReferenceProperty(FirstModel)
  reference_two = db.ReferenceProperty(FirstModel)
</pre>

<p>To avoid this error, you must explicitly set the <code>collection_name</code> argument:
 
<pre class="prettyprint">
class FirstModel(db.Model):
  prop = db.IntegerProperty()

# This class runs fine
class SecondModel(db.Model):
  reference_one = db.ReferenceProperty(FirstModel,
      collection_name="secondmodel_reference_one_set")
  reference_two = db.ReferenceProperty(FirstModel,
      collection_name="secondmodel_reference_two_set") 
</pre>

<p>Automatic referencing and dereferencing of model instances, type checking and back-references are only available using the ReferenceProperty model property class.  Keys stored as values of Expando dynamic properties or ListProperty values do not have these features.</p>


<h2 id="Property_Names">Property Names</h2>

<p>The datastore reserves all property names begining and ending with two underscore characters (<code>__*__</code>).  An application cannot create a property with such a name.</p>

<p>In the Python API, attributes of model instances whose names begin with an underscore (<code>_</code>) are ignored, and are not saved to the datastore entity.  This allows you to store values on the model instance for temporary internal use without affecting the data saved with the entity.</p>

<p>Because the Python API uses attributes of model instances as property names by default, none of the attributes already in use by instance methods can be used directly as property attribute names.  Similarly, none of the names used by the keyword arguments of model constructors can be used as property attribute names.  See <a href="modelclass.html#Disallowed_Property_Names">the list of reserved property names</a>.</p>

<p>The datastore itself allows these names.  If an application needs a datastore entity to have a property with a name similar to a word reserved in the Python API, the application can use a fixed property and pass the <code>name</code> argument to the Property class constructor.  See <a href="propertyclass.html#Property">the Property class constructor</a>.</p>

<pre class="prettyprint">
class MyModel(db.Model):
  obj_key = db.StringProperty(name="key")
</pre>



      </div><!-- end gc-pagecontent -->
   </div><!-- end gooey wrapper -->

    </div> <!-- end codesite content -->

<div id="gc-footer" dir="ltr">
  <div class="text">
    
      <div class="notice"><div id="notice" style="text-align: center; border: 1em 0em 1em 0em">
  Except as otherwise <a
  href="http://code.google.com/policies.html#restrictions">noted</a>,
  the content of this page is licensed under the <a rel="license"
  href="http://creativecommons.org/licenses/by/2.5/">Creative Commons
  Attribution 2.5 License</a>, and code samples are licensed under the
  <a rel="license" href="http://www.apache.org/licenses/LICENSE-2.0">Apache
  2.0 License</a>.
<!-- <rdf:RDF xmlns="http://web.resource.org/cc/" 
              xmlns:dc="http://purl.org/dc/elements/1.1/"
              xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <Work rdf:about="">
    <license rdf:resource="http://creativecommons.org/licenses/by/2.5/" />
  </Work>
  <License rdf:about="http://creativecommons.org/licenses/by/2.5/">
    <permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
    <permits rdf:resource="http://web.resource.org/cc/Distribution"/>
    <requires rdf:resource="http://web.resource.org/cc/Notice"/>
    <requires rdf:resource="http://web.resource.org/cc/Attribution"/>
    <permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
  </License>
</rdf:RDF> -->
</div>
Java is a registered trademark of Sun Microsystems, Inc.</div>
    
    &copy;2009 Google -
    <a href="http://code.google.com">Code Home</a> -
    <a href="http://www.google.com/accounts/TOS">Terms of Service</a> -
    <a href="http://www.google.com/privacy.html">Privacy Policy</a> -
    <a href="http://code.google.com/more">Site Directory</a>
    <br /> <br />
    Google Code offered in:
    <a href="http://code.google.com/intl/en">English</a> -
    <a href="http://code.google.com/intl/es">Español</a> -
    <a href="http://code.google.com/intl/ja">日本語</a> -
    <a href="http://code.google.com/intl/ko">한국어</a> -
    <a href="http://code.google.com/intl/pt-BR">Português</a> -
    <a href="http://code.google.com/intl/ru">Pусский</a> -
    <a href="http://code.google.com/intl/zh-CN">中文(简体)</a> -
    <a href="http://code.google.com/intl/zh-TW">中文(繁體)</a>
  </div>
</div><!-- end gc-footer -->

</div><!-- end gc-containter -->

<script type="text/javascript">CODESITE_CSITimer['load'].tick('ats');</script>
<script src="../../../../js/codesite_tail.pack.04102009.js" type="text/javascript"></script>






  </body>
</html>


